package com.lin.filter;

import com.alibaba.fastjson.JSON;
import com.lin.base.ResultCode;
import com.lin.entity.SecurityUser;
import com.lin.entity.User;
import com.lin.util.JwtUtil;
import com.lin.util.ResponseMessageUtils;
import lombok.SneakyThrows;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StreamUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author lin
 * @version 1.0
 * @Description
 * @Date 2021/1/21 18:03
 */
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl("/api/base/login");
    }

    @SneakyThrows
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        String body = StreamUtils.copyToString(request.getInputStream(), StandardCharsets.UTF_8);
        User user = JSON.parseObject(body, User.class);
        try {
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
        } catch (AuthenticationException e) {
            unsuccessfulAuthentication(request, response, e);
            return null;
        }

    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();
        String token = JwtUtil.generateJwt(securityUser);
        response.setHeader(JwtUtil.TOKEN_HEADER, JwtUtil.TOKEN_PREFIX + token);
        ResponseMessageUtils.setSuccessfulMessage(response, "登入成功");
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        ResponseMessageUtils.setFailMessage(response, ResultCode.FAIL, "认证失败");
    }
}
